﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Policy;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Data.implement;
using log4net;
using Newtonsoft.Json.Linq;
using Services.Interface;

namespace Services.Implement
{
    public class WeixinAuthService:IWeixinAuthService
    {
        private string appid;
        private string secret;
        private ILog Logger;
        public WeixinAuthService()
        {
            Logger = LogManager.GetLogger(this.GetType());
            appid = ConfigurationSettings.AppSettings["appId"];
            secret = ConfigurationSettings.AppSettings["sercet"];
        }

        public bool GetToken(string code, out string token, out string openId, out string errorCode, out  string errorMsg)
        {
            try
            {
                token = "";
                openId = "";
                errorMsg = "";
                errorCode = "";

                string url =
                    "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";
                WebRequest request = HttpWebRequest.Create(url);
                WebResponse response = request.GetResponse();
                Stream s = response.GetResponseStream();
                byte[] content = new byte[response.ContentLength];

                s.Read(content, 0, (int)response.ContentLength);

                var responseContent = Encoding.UTF8.GetString(content);
                string[] list = responseContent.TrimStart('{').TrimEnd('}').Split(',');

                foreach (var str in list)
                {
                    string[] strs = str.Split(':');
                    switch (strs[0])
                    {
                        case "\"access_token\"":
                            token = strs[1].ToString().TrimStart('\"').TrimEnd('\"');
                            break;
                        case "\"openid\"":
                            openId = strs[1].ToString().TrimStart('\"').TrimEnd('\"');
                            break;
                        case "\"errcode\"":
                            errorCode = strs[1].ToString().TrimStart('\"').TrimEnd('\"');
                            break;
                        case "\"errmsg\"":
                            errorMsg = strs[1].ToString().TrimStart('\"').TrimEnd('\"');
                            break;
                        default:
                            break;

                    }
                }

                if (!string.IsNullOrEmpty(token))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                Logger.Error("WeixinAuthService-GetToken has an error:"+e);
                token = "";
                openId = "";
                errorMsg = "";
                errorCode = "";
                return false;
                throw;
            }
            



        }

        public bool RefreshToken(string token,out string openId,out string errorMsg,out string errorCode)
        {
            try
            {
                token = string.Empty;
                errorMsg = string.Empty;
                errorCode = string.Empty;
                openId = string.Empty;

                string url = String.Format(
                    "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid={0}&grant_type=refresh_token&refresh_token={1}", appid, token);
                WebRequest request = HttpWebRequest.Create(url);
                WebResponse response = request.GetResponse();
                Stream s = response.GetResponseStream();
                byte[] content = new byte[response.ContentLength];

                s.Read(content, 0, (int)response.ContentLength);

                var responseContent = Encoding.UTF8.GetString(content);
                string[] list = responseContent.TrimStart('{').TrimEnd('}').Split(',');

                foreach (var str in list)
                {
                    string[] strs = str.Split(':');
                    switch (strs[0])
                    {
                        case "\"access_token\"":
                            token = str[1].ToString().TrimStart('"').TrimEnd('"');
                            break;
                        case "\"openid\"":
                            openId = str[1].ToString().TrimStart('"').TrimEnd('"');
                            break;
                        case "\"errcode\"":
                            errorCode = str[1].ToString().TrimStart('"').TrimEnd('"');
                            break;
                        case "\"errmsg\"":
                            errorMsg = str[1].ToString().TrimStart('"').TrimEnd('"');
                            break;
                        default:
                            break;

                    }
                }

                if (!string.IsNullOrEmpty(token))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception)
            {
                
                throw;
            }
            



        }

        public WeiXinUser PullWeiXinUser(string code, out string errorCode, out string errorMsg)
        {
            //step 2,3 and 4
            var token = string.Empty;
            var openId = string.Empty;

            if (GetToken(code, out token, out openId, out errorCode, out errorMsg))//step2
                if (errorCode != string.Empty) RefreshToken(token, out openId, out errorMsg, out errorCode);//step3
            if (errorCode != string.Empty)
                return null;
            var result = GetUser(token, openId, out errorMsg, out errorCode);//step4
            return errorCode != string.Empty ? null : result;
        }


        public WeiXinUser GetUser(string token, string openId, out string errorMsg, out string errorCode)
        {
            try
            {
                WeiXinUser user = new WeiXinUser() { openId = openId };

                errorMsg = string.Empty;
                errorCode = string.Empty;
                string url =
                    "https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + openId + "&lang=zh_CN";
                WebRequest request = HttpWebRequest.Create(url);
                request.Method = "GET";
                WebResponse response = request.GetResponse();
                Stream s = response.GetResponseStream();
                byte[] content = new byte[response.ContentLength];

                s.Read(content, 0, (int)response.ContentLength);

                var responseContent = Encoding.UTF8.GetString(content);
                JObject jObject = JObject.Parse(responseContent);
                if (jObject["errmsg"] == null)
                {
                    user.nickname = jObject["nickname"].ToString();
                    user.sex = jObject["sex"].ToString();
                    user.province = jObject["province"].ToString();
                    user.city = jObject["city"].ToString();
                    user.country = jObject["country"].ToString();
                    user.headimgurl = jObject["headimgurl"].ToString();
                }
                else
                {
                    errorMsg = jObject["errmsg"].ToString();
                    errorCode = jObject["errcode"].ToString();
                }

                if (!string.IsNullOrEmpty(token) && (user.nickname!=null) && (user.headimgurl!=null))
                {
                    return user;
                }
                else
                {
                    return null;
                }
            }
            catch (Exception e)
            {
                errorMsg = string.Empty;
                errorCode = string.Empty;
                Logger.Error("WeixinAuthService-GetUser has an error:"+e);
                return  null;
            }
            

        }
    }
}
